package com.tanhua.dubbo.api;

import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@Service
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存评论信息
     * 1. 补全评论信息: 评论时间
     * 2.  保存评论对象到comment表
     * 3. 修改publish中对应字段的值
     * 1. 根据pubType
     * 如果是动态：点赞 文评 喜欢
     * 如果是视频：点赞 文评
     * 如果是评论：点赞
     * 2. 根据commentType 确定那个字段计数值修改
     * 1 表示修改 likeCount
     * 2 表示修改 commentCount
     * 3 表示修改 loveCount
     */
    @Override
    public Integer saveComment(Comment comment) {
        //1. 补全评论信息
        comment.setId(ObjectId.get());
        comment.setCreated(System.currentTimeMillis());
        //2. 将评论信息保存到comment表中
        mongoTemplate.insert(comment);

        //3. 修改publish表中对应评论类型计数值
        return updateCount(comment, 1);
    }

    /**
     * 1. 设置删除条件
     * 根据userId, publishId, commentType可以确定唯一点赞记录
     * 2. 删除comment表中记录
     * 3. publish中对应字段计数值-1
     */
    @Override
    public Integer removeComment(Comment comment) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(comment.getUserId())
                .and("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType()));

        mongoTemplate.remove(query, Comment.class);

        return updateCount(comment, -1);
    }

    /**
     * 查询某个动态文字评论列表 commentType == 2
     *
     * @param page
     * @param pagesize
     * @param publishId
     * @return
     */
    @Override
    public PageResult findCommentListByPublishId(int page, int pagesize, ObjectId publishId) {
        Query query = new Query();
        query.addCriteria((Criteria.where("publishId").is(publishId)
                .and("commentType").is(2)));
        query.with(Sort.by(Sort.Order.desc("created")));
        query.with(PageRequest.of(page - 1, pagesize));

        List<Comment> list = mongoTemplate.find(query, Comment.class);
        long count = mongoTemplate.count(query, Comment.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult((int) count, pagesize, pages, page, list);
    }

    @Override
    public PageResult findCommentListByType(Integer page, Integer pagesize, Integer commentType, Integer pubType, Long userId) {
        switch (pubType) {
            case 1: {
                //查询对动态的评论列表
                return findCommentsList(page, pagesize, commentType, userId);
            }
            case 2:
                //TODO  查询对视频的评论列表
                return null;
            case 3:
                //TODO  查询对文字评论的评论列表
                return null;
            default:
                return null;
        }
    }


    /**
     * 修改publish中对应字段的值
     * 1. 根据pubType
     * 如果是动态：点赞 文评 喜欢
     * 如果是视频：点赞 文评
     * 如果是评论：点赞
     * 2. 根据commentType 确定那个字段计数值修改
     * 1 表示修改 likeCount
     * 2 表示修改 commentCount
     * 3 表示修改 loveCount
     */
    private Integer updateCount(Comment comment, Integer value) {
        //获取评论对象类型
        Integer pubType = comment.getPubType();
        if (pubType == 1) {
            //评论对象是动态
            //1. 获取评论类型    1 为点赞， 2 为文字评论， 3 为喜欢
            Integer commentType = comment.getCommentType();
            //2. 获取需要修改的字段
            String column = comment.getCountColumn();

            //3.1 设置修改条件
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(comment.getPublishId()));
            //3.2 设置需要修改的字段及值
            Update update = new Update().inc(column, value);
            FindAndModifyOptions options = new FindAndModifyOptions();
            options.returnNew(true);

            Publish publish = mongoTemplate.findAndModify(query, update, options, Publish.class);
            if (publish == null) {
                return null;
            }
            //4. 返回修改后的最新计数值
            if (commentType == 1) {
                return publish.getLikeCount();
            } else if (commentType == 2) {
                return publish.getCommentCount();
            } else if (commentType == 3) {
                return publish.getLoveCount();
            } else {
                return null;
            }
        } else if (pubType == 2) {
            //TODO 评论对象是视频，待完成  点赞+文评
            return null;
        } else if (pubType == 3) {
            //TODO 评论对象是评论，待完成  点赞
            return null;
        }
        return null;
    }

    //查询对当前用户所有动态评论列表
    private PageResult findCommentsList(Integer page, Integer pagesize, Integer commentType, Long userId) {
        Query query = Query.query(Criteria.where("publishUserId").is(userId)
                .and("commentType").is(commentType).and("pubType").is(1));
        query.with(Sort.by(Sort.Order.desc("created")));
        query.with(PageRequest.of(page - 1, pagesize));
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        long count = mongoTemplate.count(query, Comment.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult((int) count, pagesize, pages, page, commentList);
    }

}
